package com.myk.game.lib.eventcenter;

import android.os.Handler;
import android.os.Looper;

import java.util.ArrayList;
import java.util.List;

/**
 * 事件总线模型类，组件解耦神器
 * 同时包含里两种事件交互方式
 */
public class EventModel<T> {

    private final Handler handler = new Handler(Looper.getMainLooper());
    private final List<EventRunBack<T>> runBackList = new ArrayList<>();
    private EventDataBack<T> dataBack = () -> null;

    /**
     * 添加一个运行回调，相当于定义了一个匿名方法
     * 外界调用该方法不需要依赖定义该方法的组件
     */
    public void addRunBack(EventRunBack<T> runBack) {
        runBackList.add(runBack);
    }

    /**
     * 移除某个运行回调
     */
    public void removeRunBack(EventRunBack<?> runBack) {
        runBackList.remove(runBack);
    }

    /**
     * 移除该模型中所有运行回调
     */
    public void removeAllRunBack() {
        runBackList.clear();
    }

    /**
     * 通知该模型上的所有运行回调依次在主线程运行，
     * 不需要关心回调方法在哪个组件里定义的
     */
    public void sendRun(T data) {
        for (EventRunBack<T> runBack : runBackList) {
            handler.post(() -> runBack.onRun(data));
        }
    }

    /**
     * 设置数据回调
     * 将一个组件里获取私有数据的方法存放到该模型里
     * 外界想要获取这个组件的私有数据时，不需要依赖私有组件，只需要依赖该模型即可
     */
    public void setDataBack(EventDataBack<T> dataBack) {
        this.dataBack = dataBack;
    }

    /**
     * 设置数据回调返回null
     */
    public void setNullDataBack() {
        dataBack = () -> null;
    }

    /**
     * 接口回调的方式获取某个数据，不关心数据来源
     */
    public void getDataAsync(EventRunBack<T> runBack) {
        T data = dataBack.onBack();
        handler.post(() -> runBack.onRun(data));
    }

    /**
     * 方法返回的方式获取某个值，不关心数据来源
     */
    public T getDataSync() {
        return dataBack.onBack();
    }

}
